/*
 * @(#)JacksonUtils.java $version 2011. 9. 30.
 *
 * Copyright 2011 NHN Corp. All rights Reserved.
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.example.android.bitmapfun.model.util;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import android.util.Log;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;

/**
 * 앞으로 Jackson을 사용해 json을 파싱하는 것이 표준임.
 * mylog에서 가져온 utils. 필요한 부분만 복사해옴.
 * @author sunhwa.jung
 */
public class JacksonUtils {
	private static final String TAG = "JacksonUtils";

	private static final ObjectMapper DEFAULT_OBJECT_MAPPER;

	static {
		DEFAULT_OBJECT_MAPPER = new ObjectMapper();
	}

	/**
	 * object를 json으로 만들어 리턴한다.
	 * 예외가 발생하면 null을 리턴한다.
	 *
	 * @param mapper json 파싱을 위해 사용할 jackson의 ObjectMapper 정보
	 * @param object json으로 변경할 object
	 * @return object를 json으로 만든 결과
	 */
	public static String jsonFromObject(ObjectMapper mapper, Object object) {
		StringWriter writer = new StringWriter();
		try {
			mapper.writeValue(writer, object);
		} catch (Exception e) {
			Log.e(TAG, "Unable to serialize to json: " + e.getMessage());
			e.printStackTrace();
			return null;
		}

		return writer.toString();
	}

	/**
	 * object를 json으로 만들어 리턴한다. ObjectMapper는 기본으로 정의된 것을 사용한다.
	 * 예외가 발생하면 null을 리턴한다.
	 * @param object json으로 변경할 object
	 * @return object를 json으로 만든 결과
	 */
	public static String jsonFromObject(Object object) {
		return jsonFromObject(DEFAULT_OBJECT_MAPPER, object);
	}

	/**
	 * json을 object로 변환하여 리턴한다.
	 * 예외가 발생하면 null을 리턴한다.
	 *
	 * @param <T>
	 * @param mapper 처리 시 사용할 jackson의 ObjectMapper 정보
	 * @param json json 스트링
	 * @param clazz json으로 만들어낼  object class 정보
	 * @return json의 내용을 populate한 객체
	 */
	public static <T> T objectFromJson(ObjectMapper mapper, String json, Class<T> clazz) {
		T object;
		try {
			object = mapper.readValue(json, clazz);
		} catch (Exception e) {
			Log.e(TAG, e.getMessage() + ", json :: " + json);
			e.printStackTrace();
			return null;
		}
		return object;
	}

	/**
	 * json을 object로 변환하여 리턴한다.
	 * 예외가 발생하면 null을 리턴한다.
	 *
	 * @param <T>
	 * @param mapper 처리 시 사용할 jackson의 ObjectMapper 정보
	 * @param json json 스트링
	 * @param clazz json으로 만들어낼  object class 정보
	 * @return json의 내용을 populate한 객체
	 */
	public static <T> T objectFromJson(ObjectMapper mapper, String json, TypeReference<T> clazz) {
		T object;
		try {
			object = mapper.readValue(json, clazz);
		} catch (Exception e) {
			Log.e(TAG, e.getMessage() + ", json :: " + json);
			e.printStackTrace();
			return null;
		}
		return object;
	}

	/**
	 * json을 기본 정의된 ObjectMapper를 이용하여 해당 클래스 객체를 생성해 리턴한다.
	 * 예외가 발생하면 null을 리턴한다.
	 *
	 * @param <T>
	 * @param json json 스트링
	 * @param clazz json으로 만들어낼  object class 정보
	 * @return json의 내용을 populate한 객체
	 */
	public static <T> T objectFromJson(String json, Class<T> clazz) {
		return objectFromJson(DEFAULT_OBJECT_MAPPER, json, clazz);
	}

	/**
	 * json을 기본 정의된 ObjectMapper를 이용하여 해당 클래스 객체를 생성해 리턴한다.
	 * 예외가 발생하면 null을 리턴한다.
	 *
	 * @param <T>
	 * @param json json 스트링
	 * @param clazz json으로 만들어낼  object class 정보
	 * @return json의 내용을 populate한 객체
	 */
	public static <T> T objectFromJson(String json, TypeReference<T> clazz) {
		return objectFromJson(DEFAULT_OBJECT_MAPPER, json, clazz);
	}

	/**
	 * json 형태의 문자열에서 지정된 키값에 대한 value를 string 으로 변환하여 리턴한다.
	 *
	 * @param json json 형태로 작성된 스트링
	 * @param key 찾고자 하는 key값
	 * @return String key에 대응되는  value
	 */
	/*public static String getStringValue(String json, String key) {
		try {
			if (StringUtils.isEmpty(json)) {
				return "";
			}

			ObjectMapper objectMapper = new ObjectMapper();
			JsonNode jsonNode = objectMapper.readValue(json, JsonNode.class);

			if (jsonNode == null) {
				return "";
			}

			return jsonNode.path(key).toString();
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}*/

	public static <T> List<T> listFromJson(String json, Class<T> clazz) {
		return listFromJson(DEFAULT_OBJECT_MAPPER, json, clazz);
	}

	public static <T> List<T> listFromJson(ObjectMapper mapper, String json, Class<T> clazz) {
		List<T> list;
		try {
			TypeFactory t = TypeFactory.defaultInstance();
			list = mapper.readValue(json, t.constructCollectionType(ArrayList.class, clazz));
		} catch (Exception e) {
			Log.e(TAG, e.getMessage() + " , json :: " + json);
			e.printStackTrace();
			return null;
		}
		return list;
	}

	/**
	 * json 형태의 문자열에서 지정된 키값에 대한 value를 리턴한다.
	 *
	 * @param json json 형태로 작성된 스트링
	 * @param key 찾고자 하는 key값
	 * @return String key에 대응되는  value
	 */
	/*public static String getValue(String json, String key) {
		try {
			if (StringUtils.isEmpty(json)) {
				return "";
			}

			ObjectMapper objectMapper = new ObjectMapper();
			JsonNode jsonNode = objectMapper.readValue(json, JsonNode.class);

			if (jsonNode == null) {
				return "";
			}

			return jsonNode.path(key).textValue();
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}*/
}
